package test03;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

// 主题接口（被观察者）
interface Subject {
    void registerObserver(Observer observer);
    void removeObserver(Observer observer);
    void notifyObservers();
}

// 观察者接口
interface Observer {
    void update(Video video);
}

// 视频类
class Video {
    private String title;
    private Date publishTime;

    public Video(String title) {
        this.title = title;
        this.publishTime = new Date();
    }

    public String getTitle() {
        return title;
    }

    public Date getPublishTime() {
        return publishTime;
    }

    @Override
    public String toString() {
        return "《" + title + "》（发布时间：" + publishTime + "）";
    }
}

// 博主类（具体主题）
class Blogger implements Subject {
    private String name;
    private List<Observer> followers;
    private List<Video> videos;
    private Video latestVideo;

    public Blogger(String name) {
        this.name = name;
        this.followers = new ArrayList<>();
        this.videos = new ArrayList<>();
    }

    public String getName() {
        return name;
    }

    public List<Video> getVideos() {
        return new ArrayList<>(videos);
    }

    @Override
    public void registerObserver(Observer observer) {
        if (!followers.contains(observer)) {
            followers.add(observer);
            System.out.println(observer + " 关注了博主 " + name);
        }
    }

    @Override
    public void removeObserver(Observer observer) {
        if (followers.remove(observer)) {
            System.out.println(observer + " 取消关注博主 " + name);
        }
    }

    @Override
    public void notifyObservers() {
        if (latestVideo != null) {
            System.out.println("\n--- 博主 " + name + " 开始通知粉丝新视频发布 ---");
            for (Observer follower : followers) {
                follower.update(latestVideo);
            }
            System.out.println("--- 通知完成 ---\n");
        }
    }

    // 发布新视频
    public void publishVideo(String title) {
        this.latestVideo = new Video(title);
        videos.add(latestVideo);
        System.out.println("\n🎬 博主 " + name + " 发布了新视频：" + latestVideo);
        notifyObservers();
    }

    @Override
    public String toString() {
        return "博主[" + name + "]";
    }
}

// 粉丝类（具体观察者）
class Fan implements Observer {
    private String name;
    private Blogger followedBlogger;

    public Fan(String name) {
        this.name = name;
    }

    // 关注博主
    public void follow(Blogger blogger) {
        if (this.followedBlogger != null) {
            this.followedBlogger.removeObserver(this);
        }
        this.followedBlogger = blogger;
        blogger.registerObserver(this);
    }

    // 取消关注
    public void unfollow() {
        if (this.followedBlogger != null) {
            this.followedBlogger.removeObserver(this);
            this.followedBlogger = null;
        }
    }

    @Override
    public void update(Video video) {
        System.out.println("💌 粉丝 " + name + " 收到通知：您关注的 " +
                followedBlogger.getName() + " 发布了新视频 " + video);
    }

    @Override
    public String toString() {
        return "粉丝[" + name + "]";
    }
}

// 高级粉丝类（扩展观察者类型，体现解耦特性）
class VIPFan implements Observer {
    private String name;
    private List<Blogger> followedBloggers;

    public VIPFan(String name) {
        this.name = name;
        this.followedBloggers = new ArrayList<>();
    }

    public void follow(Blogger blogger) {
        if (!followedBloggers.contains(blogger)) {
            followedBloggers.add(blogger);
            blogger.registerObserver(this);
        }
    }

    public void unfollow(Blogger blogger) {
        if (followedBloggers.remove(blogger)) {
            blogger.removeObserver(this);
        }
    }

    @Override
    public void update(Video video) {
        System.out.println("🌟 VIP粉丝 " + name + " 收到特别通知：您关注的博主发布了新视频 " + video);
    }

    @Override
    public String toString() {
        return "VIP粉丝[" + name + "]";
    }
}

// 演示类
public class DouyinNotificationSystem {
    public static void main(String[] args) {
        System.out.println("=== 抖音视频发布通知系统演示 ===\n");

        // 创建博主
        Blogger travelBlogger = new Blogger("旅行达人小明");
        Blogger foodBlogger = new Blogger("美食博主小美");
        Blogger techBlogger = new Blogger("科技大咖老张");

        // 创建普通粉丝
        Fan fan1 = new Fan("张三");
        Fan fan2 = new Fan("李四");
        Fan fan3 = new Fan("王五");

        // 创建VIP粉丝
        VIPFan vipFan = new VIPFan("VIP用户");

        System.out.println("=== 粉丝关注博主 ===");
        // 粉丝关注博主
        fan1.follow(travelBlogger);
        fan2.follow(travelBlogger);
        fan2.follow(foodBlogger);
        fan3.follow(techBlogger);

        // VIP粉丝关注多个博主
        vipFan.follow(travelBlogger);
        vipFan.follow(foodBlogger);
        vipFan.follow(techBlogger);

        System.out.println("\n=== 博主发布视频 ===");
        // 博主发布视频
        travelBlogger.publishVideo("西藏自驾游全记录");
        foodBlogger.publishVideo("成都火锅探店");
        techBlogger.publishVideo("最新AI技术解析");

        System.out.println("=== 动态调整关注关系 ===");
        // 粉丝取消关注
        fan2.unfollow();

        // 新粉丝关注
        Fan newFan = new Fan("新粉丝小赵");
        newFan.follow(travelBlogger);

        System.out.println("\n=== 博主再次发布视频 ===");
        // 博主再次发布视频
        travelBlogger.publishVideo("云南大理旅行攻略");

        System.out.println("=== 系统解耦特性演示 ===");
        // 演示系统解耦：博主不需要知道粉丝的具体实现
        System.out.println("博主 " + travelBlogger.getName() + " 的粉丝数量: " +
                travelBlogger.getVideos().size() + " 个视频");
        System.out.println("系统支持不同类型的观察者（普通粉丝、VIP粉丝等）");
        System.out.println("博主只需调用notifyObservers()，无需关心具体的粉丝实现");

        System.out.println("\n=== 扩展新的观察者类型 ===");
        // 创建匿名粉丝（不需要关注具体博主，只接收热门视频）
        Observer anonymousFan = new Observer() {
            @Override
            public void update(Video video) {
                System.out.println("📢 系统推荐：热门新视频 " + video);
            }

            @Override
            public String toString() {
                return "匿名用户";
            }
        };

        // 匿名用户关注所有博主（演示动态添加观察者）
        travelBlogger.registerObserver(anonymousFan);
        foodBlogger.registerObserver(anonymousFan);
        techBlogger.registerObserver(anonymousFan);

        // 博主发布视频，匿名用户也会收到通知
        travelBlogger.publishVideo("冬季滑雪胜地推荐");
    }
}
